package com.taoye.thread;

import cn.hutool.core.date.DateUtil;

/**
 * 解决通知过早的问题
 *
 * @author : Mr.Tao
 * @version : 1.0
 * @date : 2022/4/4 10:31
 **/
public class Demo42 {
    public static void main(String[] args) throws InterruptedException {
        Demo42Service lock = new Demo42Service();
        Thread t = new Demo42ThreadA(lock);
        t.setName("A");
        Thread t2 = new Demo42ThreadB(lock);
        t2.setName("唤醒线程");

        //执行通知过早逻辑
        t2.start();
        Thread.sleep(100);
        t.start();
    }
}

class Demo42Service {
    /**
     * 这里模拟业务逻辑如果没有处理完成则不允许等待
     */
    private boolean canWait = true;

    public boolean isCanWait() {
        return canWait;
    }

    public void setCanWait(boolean canWait) {
        this.canWait = canWait;
    }
}


class Demo42ThreadA extends Thread {
    private Demo42Service lock;

    public Demo42ThreadA(Demo42Service lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        synchronized (lock) {
            try {
                //判断是否可以进入等待
                if (lock.isCanWait()) {
                    System.out.println("我是线程" + Thread.currentThread().getName() + "，现在开始等待，时间：" + DateUtil.now());
                    lock.wait();
                    System.out.println("我是线程" + Thread.currentThread().getName() + "，现在等待结束了，时间：" + DateUtil.now());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Demo42ThreadB extends Thread {
    private Demo42Service lock;

    public Demo42ThreadB(Demo42Service lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        synchronized (lock) {
            System.out.println("我是唤醒线程，现在开始唤醒，时间：" + DateUtil.now());
            //唤醒线程业务处理异常，A线程不用等待
            lock.setCanWait(false);
            lock.notify();
            System.out.println("我是唤醒线程，唤醒完成，时间：" + DateUtil.now());
        }
    }
}